home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / cimb.arj / GIF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-19  |  18.7 KB  |  814 lines

  1. /*==============================================================================
  2.  
  3. FICHERO: GIF.C
  4.  
  5. AUTOR: ANTONIO LADESA JURADO
  6.  
  7. FECHA: 24/6/94
  8.  
  9. DESCRIPCION:
  10.  
  11.     Fichero que contiene las estructuras, constantes, variables y funciones
  12.     internas y externas para el procesamiento de ficheros GIF.
  13.  
  14. ==============================================================================*/
  15.  
  16.  
  17. /*---- MODULOS USADOS --------------------------------------------------------*/
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <conio.h>
  22. #include <dos.h>
  23. #include <alloc.h>
  24. #include <stdlib.h>
  25. #include <dir.h>
  26. #include <io.h>
  27.  
  28. #include "global.h"
  29. #include "memoria.h"
  30. #include "video.h"
  31. #include "color.h"
  32. #include "gif.h"
  33. #include "error.h"
  34.  
  35. /*---- ESTRUCTURAS, CONSTANTES Y VARIABLES LOCALES AL MODULO -----------------*/
  36.  
  37.     /* cabecera global de un GIF */
  38. typedef struct
  39.     {
  40.     char id[6];
  41.     int ancho_pantalla;
  42.     int alto_pantalla;
  43.     char bandera_global;
  44.     char color_fondo;
  45.     char cero;
  46.     }CABgif;
  47.  
  48.     /* estructura local */
  49. typedef struct
  50.     {
  51.     int x0;
  52.     int y0;
  53.     int ancho;
  54.     int alto;
  55.     char bandera_local;
  56.     }GIFlocal;
  57.  
  58.     /* datos de entrada a la función de escritura de ficheros GIF */
  59.     /* escrita en ensamblador. Módulo GIFASM.ASM                  */
  60. typedef struct
  61.     {
  62.     unsigned int ancho_pantalla;
  63.     unsigned int alto_pantalla;
  64.     unsigned int izda_imagen;
  65.     unsigned int arriba_imagen;
  66.     unsigned int ancho_imagen;
  67.     unsigned int alto_imagen;
  68.     unsigned int fondo;
  69.     unsigned int bits;
  70.     unsigned long tam_imagen;
  71.     char *paleta;
  72.     char *origen;
  73.     char *destino;
  74.     }GIFdatos;
  75.  
  76.  
  77.     /* variables de control de lineas */
  78. int x,y;
  79.     /* buffer para la línea leida */
  80. char linea[ANCHO_MAXIMO];
  81.  
  82.     /* puntero a fichero */
  83. FILE *f;
  84.  
  85.     /* tablas y variables para la gestión del modo entrelazado */
  86. static int incremento[5]={8,8,4,2,0};
  87. static int inicio[5]={0,4,2,1,0};
  88. int entrelazado;
  89. int paso;
  90.  
  91.     /* variables usadas en la descompresión LZW */
  92. static char mascara[9] = {0,1,3,7,0xf,0x1f,0x3f,0x7f,0xff};
  93. int BufferBits,ContadorBits,ContadorBuffer,LongitudPixel;
  94.  
  95.     /* tablas LZW */
  96. char *LZWpila,*LZWultimo,*LZWprimero;
  97. int *LZWenlace;
  98.     /* indices a las tablas LZW */
  99. int SiguienteLimite,SiguienteCodigo;
  100.  
  101. /*---- DEFINICION DE LAS FUNCIONES INTERNAS ----------------------------------*/
  102.  
  103. IMAGEN *GIFleerImagen(IMAGEN *c);
  104. IMAGEN *GIFleerCabecera(IMAGEN *c,char *nombre);
  105. IMAGEN *LZWleer(IMAGEN *c,int CodigoInicio,int LongitudPixel);
  106. IMAGEN *GIFextraerPixel(IMAGEN *c,int codigo, int LongitudPixel);
  107. IMAGEN *GIFponerPixel(IMAGEN *c,int pixel);
  108. void GIFliberar(void);
  109.  
  110. int ExtraerCodigo(int LongitudCodigo);
  111. int LeerCodigo(int LongitudCodigo);
  112. int leerByte(void);
  113.  
  114. void InicializarTabla(int CodigoLimpiar);
  115. void InsertarCodigo(int codigo,int AnteriorCodigo,int *csizeptr);
  116.  
  117.     /* función de compresión LZW, en ensamblador. Módulo GIFASM.ASM */
  118. extern int LZWescribir(GIFdatos *);
  119.  
  120. /*---- CODIFICACION DE LAS FUNCIONES OFRECIDAS -------------------------------*/
  121.  
  122.  
  123. /*---- FUNCION: extern IMAGEN *GIFcargar(char *nombre,IMAGEN *c) ---------------
  124.  
  125.     Descripción:
  126.  
  127.         Esta función carga en memoria una imagen de tipo GIF.
  128.  
  129.     Parámetros:
  130.  
  131.         char *nombre : nombre del fichero a cargar
  132.         IMAGEN *c : puntero a estructura que alberga la imagen
  133.  
  134.     Retorno:
  135.  
  136.         Puntero a la estructura de la imagen o NULL si hubo error
  137.  
  138. ---- CODIGO: -----------------------------------------------------------------*/
  139.  
  140. extern IMAGEN *GIFcargar(char *nombre,IMAGEN *c)
  141. {
  142.     /* abrir fichero */
  143. if((f=fopen(nombre,"rb"))!=NULL)
  144.     {
  145.         /* leer cabecera GIF */
  146.     if((c=GIFleerCabecera(c,nombre))!=NULL)
  147.         /* leer imagen */
  148.         c = GIFleerImagen(c);
  149.     fclose(f);
  150.     }
  151. else
  152.     {
  153.     ERRORponer(ERRapertura);
  154.     return(NULL);
  155.     }
  156. return(c);
  157. }
  158.  
  159. /*---- FIN FUNCION -----------------------------------------------------------*/
  160.  
  161.  
  162. /*---- FUNCION: extern int *GIFsalvar(char *nombre,IMAGEN *c) ------------------
  163.  
  164.     Descripción:
  165.  
  166.         Esta función salva en disco una imagen con formato GIF.
  167.  
  168.     Parámetros:
  169.  
  170.         char *nombre : nombre del fichero a salvar
  171.         IMAGEN *c : puntero a estructura que alberga la imagen
  172.  
  173.     Retorno:
  174.  
  175.         - 0 si hay error
  176.         - 1 en caso contrario
  177.  
  178. ---- CODIGO: -----------------------------------------------------------------*/
  179.  
  180. extern int GIFsalvar(char *nombre,IMAGEN *c)
  181. {
  182.     /* estructura para la función de compresión */
  183. GIFdatos cgif;
  184.     /* fichero temporal */
  185. char origen[MAXDIR];
  186. FILE *temp;
  187.     /* buffer */
  188. char p[ANCHO_MAXIMO];
  189.     /* contador */
  190. int i;
  191.  
  192.     /* solo ficheros VGA 256 colores */
  193. if(c->colores != 256)
  194.     c = EscalarColores(c,256);
  195.  
  196.     /* crea fichero temporal para guardar imagen */
  197. strcpy(origen,"gif.tmp");
  198.  
  199.     /* abrir fichero */
  200. if((temp = fopen(origen,"wb"))==NULL)
  201.     {
  202.     ERRORponer(ERRapertura);
  203.     return(0);
  204.     }
  205.  
  206.     /* escribe datos de la imagen en fichero temporal */
  207. for(i = 0; i < c->alto;++i)
  208.     {
  209.     MEMleer(p,i,c);
  210.     fwrite(p,c->bytes,1,temp);
  211.     }
  212. fclose(temp);
  213.  
  214.     /* rellena estructura para la compresión */
  215. cgif.ancho_pantalla=c->ancho;
  216. cgif.alto_pantalla=c->alto;
  217. cgif.izda_imagen=0;
  218. cgif.arriba_imagen=0;
  219. cgif.ancho_imagen=c->ancho;
  220. cgif.alto_imagen=c->alto;
  221. cgif.fondo=0;
  222. cgif.bits = 8;
  223. cgif.tam_imagen = (long)c->ancho*(long)c->alto;
  224. cgif.paleta = c->paleta;
  225. cgif.origen = origen;
  226. cgif.destino = nombre;
  227.     /* comprime */
  228. i = LZWescribir(&cgif);
  229.     /* borra fichero temporal */
  230. unlink(origen);
  231.     /* detección errores */
  232. if(!i)
  233.     return(1);
  234. else
  235.     {
  236.     ERRORponer(ERRescritura);
  237.     return(0);
  238.     }
  239. }
  240.  
  241. /*---- FIN FUNCION -----------------------------------------------------------*/
  242.  
  243.  
  244. /*---- CODIFICACION DE LAS FUNCIONES INTERNAS --------------------------------*/
  245.  
  246.  
  247. /*---- FUNCION: IMAGEN *GIFleerCabecera(IMAGEN *c,char *nombre) ----------------
  248.  
  249.     Descripción:
  250.  
  251.         Esta función reserva memoria para la imagen y lee la cabecera del fichero
  252.         GIF.
  253.  
  254.     Parámetros:
  255.  
  256.  
  257.         IMAGEN *c : puntero a estructura que alberga la imagen
  258.         char *nombre : nombre del fichero a cargar
  259.  
  260.     Retorno:
  261.  
  262.         Puntero a la estructura de la imagen o NULL si hubo error
  263.  
  264. ---- CODIGO: -----------------------------------------------------------------*/
  265.  
  266. IMAGEN *GIFleerCabecera(IMAGEN *c,char *nombre)
  267. {
  268.     /* cabecera global */
  269. CABgif cab;
  270.     /* datos locales */
  271. GIFlocal img;
  272.     /* bandera de proceso de imagen */
  273. char proceso=0;
  274.     /* código leido del fichero */
  275. int codigo;
  276.  
  277.     /* leer cabecera global */
  278. if(fread((char *)&cab,sizeof(CABgif),1,f)!=sizeof(CABgif))
  279.     {
  280.         /* comprobar que es GIF */
  281.     if(memcmp(cab.id,"GIF",3) || cab.cero)
  282.         {
  283.         ERRORponer(ERRnoTratado);
  284.         return(NULL);
  285.         }        
  286.     }
  287. else
  288.     {
  289.     ERRORponer(ERRlectura);
  290.     return(NULL);
  291.     }
  292.  
  293.     /* reservar memoria para cabecera, paleta y tablas */
  294. if((c = MEMreservarCAB(c)) != NULL)
  295. if((LZWpila = (char *)malloc(4096)) != NULL)
  296. if((LZWultimo = (char *)malloc(4096)) != NULL)
  297. if((LZWprimero = (char *)malloc(4096)) != NULL)
  298. if((LZWenlace = (int *)malloc(4096*sizeof(int))) != NULL)
  299.     {
  300.         /* obtener longitud del pixel y número de colores */
  301.     LongitudPixel = ((cab.bandera_global & 0x07)+1);
  302.     c->colores = 1 << LongitudPixel;
  303.  
  304.         /* cargar cabecera estandar de la imagen */
  305.     strcpy(c->nombre,nombre);
  306.     c->ancho = cab.ancho_pantalla;
  307.     c->alto = cab.alto_pantalla;
  308.     c->bytes = cab.ancho_pantalla;
  309.     c->formato = GIF;
  310.     c->modo = VIDEOvga;
  311.     c->haypaleta = CIERTO;
  312.  
  313.         /* si hay paleta global */
  314.     if(cab.bandera_global & 0x80)
  315.             /* leerla */
  316.         if(fread((char *)c->paleta,1,c->colores*3,f) != c->colores*3)
  317.             {
  318.             GIFliberar();
  319.             c = MEMliberar(c);
  320.             return(c);
  321.             }
  322.  
  323.         /* procesar los datos de la imagen */
  324.     while(!proceso)
  325.         {
  326.             /* leer código */
  327.         codigo = fgetc(f);
  328.         switch(codigo)
  329.             {
  330.                 /* código de imagen */
  331.             case ',':
  332.                     /* leer datos locales */
  333.                 fread((char *)&img,sizeof(img),1,f);
  334.                 entrelazado = (0x40 & img.bandera_local);
  335.                 c->ancho = img.ancho;
  336.                 c->alto = img.alto;
  337.                 c->bytes = img.ancho;
  338.  
  339.                     /* si hay paleta local, se lee y se usa, si no, se usa la global */
  340.                 if(0x80 & img.bandera_local)
  341.                     {
  342.                         /* obtener longitud del pixel y número de colores */
  343.                     LongitudPixel =  ((img.bandera_local & 0x07)+1);
  344.                     c->colores = 1 << LongitudPixel;
  345.                         /* leer paleta local */
  346.                     if(fread((char *)c->paleta,1,c->colores*3,f) != c->colores*3)
  347.                         {
  348.                         GIFliberar();
  349.                         c = MEMliberar(c);
  350.                         return(c);
  351.                         }
  352.                     }
  353.                     /* ya están los datos de la imagen, incrementar y salir */
  354.                 proceso++;
  355.             break;
  356.  
  357.                 /* extension, no tratada, se lee completa y continúa el proceso */
  358.             case '!':
  359.                 {
  360.                 int contador;
  361.  
  362.                 codigo = fgetc(f);
  363.                 for(;;)
  364.                     {
  365.                     contador = fgetc(f);
  366.                     if(!contador)
  367.                         break;
  368.                     while(contador--)
  369.                         codigo = fgetc(f);
  370.                     }
  371.                 }
  372.             break;
  373.  
  374.             default:
  375.                 GIFliberar();
  376.                 c = MEMliberar(c);
  377.                 ERRORponer(ERRlectura);
  378.             return(c);
  379.             }
  380.         }
  381.     }
  382. else
  383.     /* si no hay memoria para todo, liberar */
  384.     {
  385.     GIFliberar();
  386.     c = MEMliberar(c);
  387.     ERRORponer(ERRnoImagen);
  388.     ERRORver();
  389.     return(c);
  390.     }
  391. return(c);
  392. }
  393.  
  394. /*---- FIN FUNCION -----------------------------------------------------------*/
  395.  
  396.  
  397. /*---- FUNCION: IMAGEN *GIFleerImagen(IMAGEN *c) -------------------------------
  398.  
  399.     Descripción:
  400.  
  401.         Esta función carga en memoria una imagen de tipo GIF.
  402.  
  403.     Parámetros:
  404.  
  405.         IMAGEN *c : puntero a estructura que alberga la imagen
  406.  
  407.     Retorno:
  408.  
  409.         Puntero a la estructura de la imagen
  410.  
  411. ---- CODIGO: -----------------------------------------------------------------*/
  412.  
  413. IMAGEN *GIFleerImagen(IMAGEN *c)
  414. {
  415. int CodigoInicio;
  416.     /* leer código de inicio */
  417. CodigoInicio = fgetc(f);
  418.     /* descompactar imagen */
  419. LZWleer(c,CodigoInicio,LongitudPixel);
  420.     /* leer fin fichero */
  421. fgetc(f);
  422.     /* liberar memoria usada por las tablas LZW */
  423. GIFliberar();
  424. return(c);
  425. }
  426.  
  427. /*---- FIN FUNCION -----------------------------------------------------------*/
  428.  
  429.  
  430. /*---- FUNCION: void GIFliberar(void) ------------------------------------------
  431.  
  432.     Descripción:
  433.  
  434.         Esta función libera la memoria dinámica reservada para las tablas LZW.
  435.  
  436. ---- CODIGO: -----------------------------------------------------------------*/
  437.  
  438. void GIFliberar(void)
  439. {
  440.     /* liberar tablas LZW */
  441. if(LZWpila!=NULL) free(LZWpila);
  442. if(LZWultimo!=NULL) free(LZWultimo);
  443. if(LZWprimero!=NULL)free(LZWprimero);
  444. if(LZWenlace!=NULL) free(LZWenlace);
  445. }
  446.  
  447. /*---- FIN FUNCION -----------------------------------------------------------*/
  448.  
  449.  
  450. /*---- FUNCION: IMAGEN *GIFponerPixel(IMAGEN *c,int pixel) ---------------------
  451.  
  452.     Descripción:
  453.  
  454.         Esta función lleva un pixel a su correspondiente posición x,y en memoria.
  455.         Se actualizan las variables globales x,y.
  456.  
  457.     Parámetros:
  458.  
  459.         IMAGEN *c : puntero a estructura que alberga la imagen
  460.  
  461.         int pixel: color de pixel.
  462.  
  463.     Retorno:
  464.  
  465.         Puntero a la estructura de la imagen
  466.  
  467. ---- CODIGO: -----------------------------------------------------------------*/
  468.  
  469. IMAGEN *GIFponerPixel(IMAGEN *c,int pixel)
  470. {
  471.     /* poner pixel en la línea */
  472. linea[x++]=pixel;
  473.  
  474.     /* si la línea esta completa */
  475. if(x == c->ancho)
  476.     {
  477.         /* mandar línea a la memoria */
  478.     MEMescribir(linea,y,c);
  479.     x = 0;
  480.         /* si hay modo entrelazado, calcular siguiente linea */
  481.     if(entrelazado)
  482.         {
  483.         y += incremento[paso];
  484.         if(y >= c->alto)
  485.             y = inicio[++paso];
  486.         }
  487.     else
  488.         ++y;
  489.     }
  490. return(c);
  491. }
  492.  
  493. /*---- FIN FUNCION -----------------------------------------------------------*/
  494.  
  495.  
  496. /*-- FUNCION: IMAGEN *GIFextraerPixel(IMAGEN *c,int codigo,int LongitudPixel) --
  497.  
  498.     Descripción:
  499.  
  500.         Esta función extrae una sucesión de pixels de la tabla.
  501.         Estos pixels son los contenidos en código.
  502.  
  503.     Parámetros:
  504.  
  505.         IMAGEN *c : puntero a estructura que alberga la imagen
  506.         int codigo: código leído y descomprimido por el algoritmo
  507.         int LongitudPixel: longitud del pixel.
  508.  
  509.     Retorno:
  510.  
  511.         Puntero a la estructura de la imagen
  512.  
  513. ---- CODIGO: -----------------------------------------------------------------*/
  514.  
  515. IMAGEN *GIFextraerPixel(IMAGEN *c,int codigo, int LongitudPixel)
  516. {
  517.     /* pixels totales a extraer */
  518. int contador = 0;
  519.     /* puntero auxiliar */
  520. char *p;
  521.  
  522.     /* puntero al inicio de la pila */
  523. p = LZWpila;
  524. do
  525.     {
  526.         /* introducir dato en la pila */
  527.     *p = LZWultimo[codigo];
  528.     p++;
  529.     contador++;
  530.         /* obtener siguiente dato usando la tabla de enlace */
  531.     codigo = LZWenlace[codigo];
  532.     }
  533. while(codigo != -1);
  534.  
  535.     /* llevar pixels a la memoria */
  536. if(LongitudPixel == 1)
  537.     {
  538.     do
  539.         {
  540.         p--;
  541.         c=GIFponerPixel(c,*p & 0x0001);
  542.         c=GIFponerPixel(c,(*p & 0x00ff) >> 1);
  543.         }
  544.     while(--contador);
  545.     }
  546. else
  547.     {
  548.     do
  549.         {
  550.         p--;
  551.         c=GIFponerPixel(c,*p & 0x00ff);
  552.         }
  553.     while(--contador);
  554.     }
  555. return(c);
  556. }
  557.  
  558. /*---- FIN FUNCION -----------------------------------------------------------*/
  559.  
  560.  
  561. /*-- FUNCION: IMAGEN *LZWleer(IMAGEN *c,int CodigoInicio,int LongitudPixel) ----
  562.  
  563.     Descripción:
  564.  
  565.         Esta función reproduce el algoritmo de descompresión LZW.
  566.         Lee códigos del fichero y los introduce en la tabla.
  567.         También se encarga de enviar los pixels a la memoria.
  568.  
  569.     Parámetros:
  570.  
  571.         IMAGEN *c : puntero a estructura que alberga la imagen
  572.         int CodigoInicio: Primer código leido.
  573.         int LongitudPixel: longitud del pixel.
  574.  
  575.     Retorno:
  576.  
  577.         Puntero a la estructura de la imagen
  578.  
  579. ---- CODIGO: -----------------------------------------------------------------*/
  580.  
  581. IMAGEN *LZWleer(IMAGEN *c,int CodigoInicio,int LongitudPixel)
  582. {
  583.     /* código leido */
  584. int codigo;
  585.     /* código leido anteriormente */
  586. int AnteriorCodigo;
  587.     /* longitud del código */
  588. int LongitudCodigo;
  589.     /* código de borrado */
  590. int CodigoLimpiar;
  591.     /* código de fin */
  592. int CodigoFin;
  593.  
  594.     /* reservar memoria para la imagen */
  595. if((c = MEMreservar(c))==NULL)
  596.     {
  597.     c = MEMliberar(c);
  598.     return(c);
  599.     }
  600.  
  601.     /* inicializar variables */
  602. ContadorBuffer = 0;
  603. BufferBits = ContadorBits = 0;
  604. CodigoLimpiar= 1 << CodigoInicio;
  605. CodigoFin=CodigoLimpiar+1;
  606. LongitudCodigo=CodigoInicio+1;
  607. InicializarTabla(CodigoLimpiar);
  608. AnteriorCodigo= -1;
  609. paso =0;
  610. x = y = 0;
  611.  
  612. while(1)
  613.     {
  614.         /* leer código */
  615.     codigo = ExtraerCodigo(LongitudCodigo);
  616.  
  617.         /* si es código de borrado, inicializar la tabla */
  618.     if(codigo == CodigoLimpiar)
  619.         {
  620.             /* inicializar la tabla de códigos */
  621.         InicializarTabla(CodigoLimpiar);
  622.         LongitudCodigo=CodigoInicio+1;
  623.         AnteriorCodigo=-1;
  624.         continue;
  625.         }
  626.     else
  627.             /* si es código de final, terminar */
  628.         if(codigo == CodigoFin)
  629.             break;
  630.         else
  631.                 /* si es código de imagen, insertarlo en la tabla */
  632.             if(LZWenlace[codigo] != -2)
  633.                 {
  634.                 if(AnteriorCodigo != -1)
  635.                     InsertarCodigo(codigo,AnteriorCodigo,&LongitudCodigo);
  636.                 }
  637.             else
  638.                 InsertarCodigo(AnteriorCodigo,AnteriorCodigo,&LongitudCodigo);
  639.         /* tratar código, extrayendo pixels */
  640.     c=GIFextraerPixel(c,codigo,LongitudPixel);
  641.     AnteriorCodigo=codigo;
  642.     }
  643. return(c);
  644. }
  645.  
  646. /*---- FIN FUNCION -----------------------------------------------------------*/
  647.  
  648.  
  649. /*-- FUNCION: int ExtraerCodigo(int LongitudCodigo) ----------------------------
  650.  
  651.     Descripción:
  652.  
  653.         Esta función lee del buffer de entrada un código de longitud
  654.         LongitudCodigo bits.
  655.  
  656.     Parámetros:
  657.  
  658.         int LongitudCodigo: longitud del código en bits.
  659.  
  660.     Retorno:
  661.  
  662.         Código leído
  663.  
  664. ---- CODIGO: -----------------------------------------------------------------*/
  665.  
  666. int ExtraerCodigo(int LongitudCodigo)
  667. {
  668.     /* si ocupa un solo byte */
  669. if(LongitudCodigo<=8)
  670.     return(LeerCodigo(LongitudCodigo));
  671.     /* si ocupa dos */
  672. return(LeerCodigo(8) | ((LeerCodigo(LongitudCodigo-8))<<8));
  673. }
  674.  
  675. /*---- FIN FUNCION -----------------------------------------------------------*/
  676.  
  677.  
  678. /*-- FUNCION: int LeerCodigo(int LongitudCodigo) -------------------------------
  679.  
  680.     Descripción:
  681.  
  682.         Esta función lee del buffer de entrada un código de 8 bits y lo
  683.         devuelve ajustado LongitudCodigo bits.
  684.  
  685.     Parámetros:
  686.  
  687.         int LongitudCodigo: longitud del código en bits.
  688.  
  689.     Retorno:
  690.  
  691.         Código leído
  692.  
  693. ---- CODIGO: -----------------------------------------------------------------*/
  694.  
  695. int LeerCodigo(int LongitudCodigo)
  696. {
  697.     /* código a devolver */
  698. int codigo;
  699.     /* si no quedan bits leidos anteriormente, leer un byte */
  700. if(ContadorBits == 0)
  701.     {
  702.     BufferBits= leerByte();
  703.     ContadorBits=8;
  704.     }
  705.     /* si quedan bits pero no hay suficientes, leer byte y ajustarlo */
  706. if(ContadorBits < LongitudCodigo)
  707.     {
  708.     BufferBits |= leerByte() << ContadorBits;
  709.     ContadorBits +=8;
  710.     }
  711.     /* extraer LongitudCodigo bits del buffer */
  712. codigo = BufferBits & mascara[LongitudCodigo];
  713. ContadorBits -= LongitudCodigo;
  714. BufferBits = BufferBits >> LongitudCodigo;
  715. return(codigo);
  716. }
  717.  
  718. /*---- FIN FUNCION -----------------------------------------------------------*/
  719.  
  720.  
  721. /*-- FUNCION: int LeerByte(void) -----------------------------------------------
  722.  
  723.     Descripción:
  724.  
  725.         Esta función lee un byte del fichero procesando los paquetes en los
  726.         que se encuentran los datos.
  727.  
  728.     Retorno:
  729.  
  730.         Byte leído del fichero.
  731.  
  732. ---- CODIGO: -----------------------------------------------------------------*/
  733.  
  734. int leerByte(void)
  735. {
  736. int dato;
  737.     /* si se acabó el paquete, leer contador */
  738. if(ContadorBuffer==0)
  739.     ContadorBuffer = fgetc(f);
  740.     /* leer dato */
  741. dato = fgetc(f);
  742.     /* decrementar contador */
  743. ContadorBuffer--;
  744. return(dato);
  745. }
  746.  
  747. /*---- FIN FUNCION -----------------------------------------------------------*/
  748.  
  749.  
  750. /*-- FUNCION: void InicializarTabla(int CodigoLimpiar) -------------------------
  751.  
  752.     Descripción:
  753.  
  754.         Esta función inicializa la tabla LZW con el código de borrado como límite
  755.  
  756.     Parámetros:
  757.  
  758.         int CodigoLimpiar: código de borrado.
  759.  
  760. ---- CODIGO: -----------------------------------------------------------------*/
  761.  
  762. void InicializarTabla(int CodigoLimpiar)
  763. {
  764.     /* contador */
  765. int c=0;
  766.     /* primer código libre en la tabla */
  767. SiguienteCodigo=CodigoLimpiar+2;
  768.     /* límite para el código */
  769. SiguienteLimite=CodigoLimpiar << 1;
  770. while(c < CodigoLimpiar)
  771.     {
  772.     LZWprimero[c]=c;
  773.     LZWultimo[c]=c;
  774.     LZWenlace[c++]=-1;
  775.     }
  776. while(c < 4096)
  777.     LZWenlace[c++]= -2;
  778. }
  779.  
  780. /*---- FIN FUNCION -----------------------------------------------------------*/
  781.  
  782.  
  783. /*-- FUNCION: void InsertarCodigo(int NuevoCodigo,                 -------------
  784.                                                                     int AnteriorCodigo,
  785.                                                                     int *LongitudCodigo)
  786.  
  787.     Descripción:
  788.  
  789.         Esta función inserta un código en la tabla LZW.
  790.  
  791.     Parámetros:
  792.  
  793.         int NuevoCodigo: código a insertar.
  794.         int AnteriorCodigo: código anterior.
  795.         int *LongitudCodigo: longitud del código en bits.
  796.  
  797. ---- CODIGO: -----------------------------------------------------------------*/
  798.  
  799. void InsertarCodigo(int NuevoCodigo,int AnteriorCodigo,int *LongitudCodigo)
  800. {
  801. LZWenlace[SiguienteCodigo]=AnteriorCodigo;
  802. LZWultimo[SiguienteCodigo]=LZWprimero[NuevoCodigo];
  803. LZWprimero[SiguienteCodigo]=LZWprimero[AnteriorCodigo];
  804.     /* si se hace pequeña, ampliar la longitud del código */
  805. if(++SiguienteCodigo == SiguienteLimite)
  806.     if(*LongitudCodigo < 12)
  807.         {
  808.         (*LongitudCodigo)++;
  809.         SiguienteLimite = SiguienteLimite << 1;
  810.         }
  811. }
  812.  
  813. /*---- FIN FUNCION -----------------------------------------------------------*/
  814.